#pragma once

#include <iostream>
#include <sys/epoll.h>
#include <string.h>
#include "nocopy.hpp"
#include "Log.hpp"

static const int size = 128;


class Epoller : public NoCopy
{
public:
    Epoller()
    {
        m_epfd = epoll_create(size);
        if(m_epfd == -1)
        {
            log(ERROR, "eppol_create error: %s", strerror(errno));
        }
        else{
            log(INFO, "epoll_create success, m_epfd: %d", m_epfd);
        }
    }

    int EpollerWait(struct epoll_event revents[], int num, int timeout)
    {
        // int n = epoll_wait(m_epfd, revents, num, m_timeout);  // 每m_timeout时间
        // int n = epoll_wait(m_epfd, revents, num, 0);  // 非阻塞
        // int n = epoll_wait(m_epfd, revents, num, -1);  // 阻塞
        int n = epoll_wait(m_epfd, revents, num, timeout);  // 阻塞
        return n;
    }

    int EpollerUpdate(int oper, int sock, uint32_t event)
    {
        int n = 0;
        if(oper == EPOLL_CTL_DEL)
        {
            n = epoll_ctl(m_epfd, oper, sock, nullptr);
            if(n != 0)
            {
                log(ERROR, "delete epoll_ctl error...");
            }
        }
        else
        {
            // EPOLL_CTL_ADD || EPOLL_CTL_MOD
            struct epoll_event ev;
            ev.events = event;
            ev.data.fd = sock;  // 方便我们后期得知，是哪一个文件描述符就绪。

            n = epoll_ctl(m_epfd, oper, sock, &ev);
            if(n != 0)
            {
                log(ERROR, "epoll_ctl error...");
            }

        }   
        return n;
    }

    ~Epoller()
    {
        if(m_epfd >= 0)
        {
            close(m_epfd);
        }
    }
private:
    int m_epfd;
    int m_timeout = 3000;
};